<template>
  <div class="box">
    <div class="menu-box"> <Menu @add="addComponent" /><!-- 组件栏 --> </div>
    <div class="resize-layout">
      <div class="resize-left" ref="left">
        <!-- 中间区域 -->
        <div class="content-box">
          <MobileLayout :key="data.renderKey">
            <template #designContent>
              <a-row :gutter="0" v-model:layout="data.list" v-if="data.list.length > 0">
                <a-col
                  class="gutter-row mb-3"
                  :span="24"
                  v-for="(item, index) in data.list"
                  :key="item.i"
                  :class="{
                    'active-item': item.i === currentId,
                    '-ml-10px': item.type == 'Banner',
                  }"
                  :style="{
                    maxWidth: item.type == 'Banner' ? 'calc(100% + ' + 20 + 'px)' : '100%',
                  }"
                  @click="changeSelect(index)"
                >
                  <component
                    :id="item.i"
                    :h="item.h"
                    :type="item.type"
                    v-model:config="item.config"
                    :title="item.config.title"
                    class="item-box"
                    :is="getLegendComponent(item.type)"
                  />
                  <div class="mask">
                    <div class="button-list" v-if="item.i === currentId">
                      <a-button shape="circle" size="small" danger class="delete-button">
                        <Icon
                          icon="formkit:trash"
                          class="action-delete"
                          @click.stop="removeComponent(index)"
                        />
                      </a-button>
                    </div>
                  </div>
                </a-col>
              </a-row>
              <div v-if="data.list.length == 0" class="empty-box">
                <DesktopDesignEmpty class="empty" />
              </div>
            </template>
          </MobileLayout>
        </div>
      </div>
      <div class="resize-right" ref="right">
        <div class="right-box" v-if="data.list.length > 0">
          <!-- 属性 -->
          <div v-for="(item, index) in data.list" :key="index">
            <component
              v-show="data.currentComponentIndex == index"
              :is="getComponentProperties(item.type)"
              :info="item"
            />
          </div>
        </div>
      </div>
    </div>
    <Title :title="propertiesTitle" class="fewer-panel-box" />
  </div>
</template>

<script setup lang="ts">
  import { computed, onMounted, onUnmounted, reactive, ref } from 'vue';

  import Menu from './Menu.vue';
  import Title from './Title.vue';
  import { Icon } from '/@/components/Icon';
  import { DesktopInfoItem } from '/@/model/mobileDesign/designer';
  import { DesktopDesignEmpty } from '/@/components/ModalPanel';
  import { DesktopComponent } from '/@/enums/desktop';
  import { cloneDeep } from 'lodash-es';
  import { defaultInfo, InfoByType } from './config/info';
  import { componentTitleFromType } from './config/components';
  import MobileLayout from '../../../components/mobileLayout.vue';
  import useComponentByType from '../../hooks/useComponentByType';
  let left = ref();
  let right = ref();
  let showPanel = ref(false);

  const props = withDefaults(
    defineProps<{
      list: Array<DesktopInfoItem>;
    }>(),
    {
      list: () => {
        return [];
      },
    },
  );
  const { componentByType } = useComponentByType();
  const data: {
    currentComponentIndex: number;
    renderKey: number;
    list: Array<DesktopInfoItem>;
  } = reactive({
    currentComponentIndex: -1,
    list: [],
    renderKey: 0,
  });
  const currentId = computed(() => {
    return data.list.length > 0 ? data.list[data.currentComponentIndex].i : 0;
  });
  const currentInfo = computed(() => {
    return data.list.length > 0 ? data.list[data.currentComponentIndex] : null;
  });
  const propertiesTitle = computed(() => {
    return showPanel.value && currentInfo.value
      ? componentTitleFromType.get(currentInfo.value.type)
      : null;
  });

  onMounted(() => {
    initDisplay();
    window.addEventListener('resize', () => {
      resetDisplay();
    });
  });
  onUnmounted(() => {
    window.removeEventListener('resize', () => {
      resetDisplay();
    });
  });
  function initDisplay() {
    data.list = [];
    if (props.list && props.list.length > 0) {
      data.list = props.list;
      data.currentComponentIndex = 0;
    }
  }

  function addComponent(type: DesktopComponent) {
    let info: DesktopInfoItem | undefined = defaultInfo;
    if (InfoByType.has(type)) {
      info = InfoByType.get(type);
    }
    if (info) {
      info.i = Date.now() + '_' + Math.ceil(Math.random() * 99999);
      data.list.push(cloneDeep(info));
      data.currentComponentIndex = data.list.length - 1;
      showPropertiesBox();
    }
  }

  function showPropertiesBox() {
    if (!showPanel.value) {
      showRightBox();
    }
  }
  function removeComponent(index: number) {
    data.currentComponentIndex = 0;
    data.list.splice(index, 1);
    if (data.list.length <= 0) hidePropertiesBox();
  }
  function hidePropertiesBox() {
    if (showPanel.value) {
      hideRightBox();
    }
  }
  function changeSelect(index: number) {
    data.currentComponentIndex = index;
    showPropertiesBox();
  }
  function resetDisplay() {
    data.renderKey++;
  }
  function getLegendComponent(type: DesktopComponent) {
    return componentByType.has(type)
      ? componentByType.get(type)?.legend
      : componentByType.get(DesktopComponent.DEFAULT)?.legend;
  }

  function getComponentProperties(type) {
    return componentByType.has(type)
      ? componentByType.get(type)?.properties
      : componentByType.get(DesktopComponent.DEFAULT)?.properties;
  }
  function showRightBox() {
    showPanel.value = true;
    left.value.style.width = '75%';
    right.value.style.width = '25%';
    resetDisplay();
  }
  function hideRightBox() {
    showPanel.value = false;
    left.value.style.width = '100%';
    right.value.style.width = '0';
    resetDisplay();
  }
  function getDesignData() {
    return data.list;
  }
  async function saveDesignData() {
    return data.list;
  }

  defineExpose({
    saveDesignData,
    getDesignData,
  });
</script>

<style lang="less" scoped>
  .box {
    position: relative;
    width: 100%;
    height: 100%;
  }

  .menu-box {
    width: 58px;
    height: 100%;
    background-color: #fff;
    position: absolute;
    left: 0;
    border-right: 10px solid rgb(240 242 245);
  }

  .resize-layout {
    display: flex;
    height: 100%;
    width: 100%;
  }

  .resize-left {
    width: 100%;
    padding: 0;
    overflow: hidden;
  }

  .resize-shrink-sidebar {
    cursor: col-resize;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .shrink-sidebar-text {
    border-radius: 4px;

    /* color: #fff; */
  }

  .shrink-sidebar:hover {
    color: #666;
  }

  .resize-right {
    width: 0;

    /* 右侧初始化宽度 */
    background-color: #fff;
  }

  .right-box {
    height: 100%;
    margin-right: 10px;
  }

  .fewer-panel-box {
    width: 25%;
    position: fixed;
    top: 60px;
    left: auto;
    z-index: 3;
    right: 0;
    height: 44px;
    line-height: 46px;
    color: #262626;
    font-size: 16px;
    padding-left: 8px;
    background-color: #fff;
    font-weight: 400;

    &.item-title::after {
      content: '';
      display: block;
      position: absolute;
      height: 1px;
      bottom: 0;
      left: 0;
      right: 0;
      background-color: #f0f0f0;
    }
  }

  .content-box {
    height: 100%;
    padding-left: 58px;
    overflow: auto;
    padding-bottom: 60px;
    border-right: 10px solid rgb(240 242 245);
    background: #fff;
  }

  .vue-grid-layout {
    // background: #eee;
    height: 100%;
  }

  .button-list {
    position: absolute;
    right: -76px;
    top: 0;
  }

  .action-clone {
    color: @primary-color;
  }

  .clone-button {
    background-color: #eff4ff;
    margin-right: 4px;
  }

  .delete-button {
    margin-right: 4px;
  }

  .action-delete {
    color: @clear-color;
  }

  .mask {
    position: absolute;
    inset: 0;
    padding: 2px;
  }

  .active-item {
    border: 1px dashed #39f;
  }

  .item-box {
    position: relative;
    background-color: #fff;
    width: 100%;
    height: 100%;
    min-width: 10px;
    min-height: 10px;
    box-shadow: 0 0 5px rgb(0 0 0 / 4.7%);
  }

  .vue-grid-item:hover {
    border: 1px dotted #39f;
  }

  .empty-box {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;

    .empty {
      width: 480px;
    }
  }
</style>
